package controller

import (
	"devops/code"
	"devops/controller/validation"
	"devops/middleware"
	"devops/models"
	"devops/service"
	"fmt"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
)

// @Summary 运行流水线
// @Tags 流水线操作
// @Produce  json
// @Param	param  body  validation.PiplineRun  true   "传入参数"
// @Success 200 {object} data.SuccessRun  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 12001 {object} data.FailRun     		"错误返回"
// @Router /api/pipeline/run [post]
func RunPipline(c *gin.Context) {
	var param validation.PiplineRun
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	user := c.MustGet("curUser").(middleware.User)
	build, err := devops.PiplineRun(param.ProjectId, param.CID, user)
	if err != nil {
		ErrorResponse(c, code.BUILD_FAIL, err.Error())
		return
	}
	// 记录事件
	go devops.BuildEvent(service.BuildRun, &user, *build)
	SuccessResponse(c, build)
}

func StopPipline(c *gin.Context) {
	var param validation.PiplineStop
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	err := devops.PiplineStop(param.ProjectId, param.CID, param.BuildID)
	if err != nil {
		ErrorResponse(c, code.BUILD_FAIL, err.Error())
		return
	}
	// 记录事件
	user := c.MustGet("curUser").(middleware.User)
	go devops.BuildEvent(service.BuildStop, &user, *models.GetBuildByID(param.BuildID))
	SuccessResponse(c, "中止成功")
}

func AgainPipline(c *gin.Context) {
	//var param validation.PiplineStop
	//if err := c.ShouldBind(&param); err != nil {
	//	ErrorResponse(c, code.PARAMETER_ERR, err.Error())
	//	return
	//}
	//devops := service.NewDevOps()
	//err := devops.PiplineStop(param.ProjectId, param.CID, param.BuildID)
	//if err != nil {
	//	ErrorResponse(c, code.BUILD_FAIL, err.Error())
	//	return
	//}
	//SuccessResponse(c, "中止成功")
}

// @Summary 构建记录详情页
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetPipline  true   "传入参数"
// @Success 200 {object} data.SuccessGetBuild  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 12000 {object} data.FailGetBuild     		"错误返回"
// @Router /api/pipeline/build/one [get]
//func GetPipline(c *gin.Context) {
//	var param validation.GetPipline
//	if err := c.ShouldBind(&param); err != nil {
//		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
//		return
//	}
//	devops := service.NewDevOps()
//	stages, err := devops.GetBuildStage(param.BuildID)
//	if err != nil && stages == nil {
//		ErrorResponse(c, code.BUILD_NOT_FOUND, err.Error())
//		return
//	}
//	SuccessResponse(c, stages)
//}

// @Summary 测试报告
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetTestReport  true    "传入参数"
// @Success 200 {object} data.SuccessGetTestReport  		"成功返回"
// @Failure 10000 {object} data.ParamError     				"错误返回"
// @Router /api/pipeline/build/testReport [get]
func GetTestReport(c *gin.Context) {
	var param validation.GetTestReport
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	SuccessResponse(c, devops.GetTestReport(param.BuildID))
}

// @Summary 构建产物
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetTestReport  true   "传入参数"
// @Success 200 {object} data.SuccessGetArtifacts  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Router /api/pipeline/build/artifacts [get]
func GetArtifacts(c *gin.Context) {
	var param validation.GetTestReport
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	SuccessResponse(c, devops.GetArtifact(param.BuildID))
}

// @Summary 下载构建产物
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.DownloadArtifact  true   "传入参数"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 404 {object} data.FailDownload     			"错误返回"
// @Router /api/pipeline/build/artifacts/download [get]
func DownloadArtifact(c *gin.Context) {
	var param validation.DownloadArtifact
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	content := devops.DownloadArtifact(param.Path)
	if content == nil {
		ErrorResponse(c, code.NOTFOUND, "文件未找到")
		return
	}
	c.Writer.WriteHeader(http.StatusOK)
	c.Header("Content-Disposition", "attachment; filename="+param.Name)
	c.Header("Content-Type", "application/octet-stream") //application/text/plain
	c.Header("Accept-Length", fmt.Sprintf("%d", len(content)))
	c.Writer.Write(content)
}

// @Summary 构建记录列表
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetAllPipline  true  "传入参数"
// @Success 200 {object} data.SuccessGetBuildAll  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Router /api/pipeline/build/all [get]
func GetAllPipline(c *gin.Context) {
	var param validation.GetAllPipline
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}

	validation.CheckPage(&param.Page)
	devops := service.NewDevOps()
	build, total := devops.GetAllPiplineBuild(param.ProjectId, param.CID, param.Page.Page, param.Page.PageSize)
	SuccessPaginateResponse(c, build, total, param.Page.Page, param.Page.PageSize)
}

// @Summary 轮询获取构建记录的步骤
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetStage  true  "传入参数"
// @Success 200 {object} data.SuccessGetStage  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 12004 {object} data.FailGetStage     			"错误返回"
// @Router /api/pipeline/build/stage [get]
func GetStage(c *gin.Context) {
	var param validation.GetStage
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}

	devops := service.NewDevOps()
	stageInfo, err := devops.GetStage(param.ProjectId, param.CiName, param.BuildID)
	if err != nil {
		ErrorResponse(c, code.GET_STAGE_ERR, err.Error())
		return
	}
	SuccessResponse(c, stageInfo)
}

// @Summary 获取记录简要步骤
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetStageSimple  true  "传入参数"
// @Success 200 {object} data.SuccessGetStageSimple  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Router /api/pipeline/build/stage/simple [post]
func GetStageSimple(c *gin.Context) {
	var param validation.GetStageSimple
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}

	devops := service.NewDevOps()
	stageInfo := devops.GetBuildStageSimple(param.BuildIDs)
	SuccessResponse(c, stageInfo)
}

// @Summary 构建步骤日志
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetStageInfo  true  "传入参数"
// @Success 200 {object} data.SuccessGetStageLog  			"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Router /api/pipeline/build/stage/flow/log [get]
func GetStageInfoLog(c *gin.Context) {
	var param validation.GetStageInfo
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	info := devops.GetStageInfoLog(param.FlowID)
	SuccessResponse(c, info)
}

// @Summary 删除构建记录
// @Tags 构建记录
// @Produce  json
// @Param	param  body  validation.DeleteBuild  true   "传入参数"
// @Success 200 {object} data.SuccessDeleteBuild  		"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 11001 {object} data.FailDeleteBuild     	"错误返回"
// @Router /api/pipeline/build/delete [post]
func DeleteBuild(c *gin.Context) {
	var param validation.DeleteBuild
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	err := devops.DeleteBuild(param.BuildID)
	if err != nil {
		ErrorResponse(c, code.DELETE_FAIL, err.Error())
		return
	}

	SuccessResponse(c, "删除成功")
}

// @Summary 获取完整日志
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetBuildConsoleOutput  true   "传入参数"
// @Success 200 {object} data.SuccessGetBuildConsoleOutput  		"成功返回"
// @Failure 10000 {object} data.ParamError     			"错误返回"
// @Failure 12003 {object} data.FailGetBuildConsoleOutput     	"错误返回"
// @Router /api/pipeline/build/console/output [get]
func GetBuildConsoleOutput(c *gin.Context) {
	var param validation.GetBuildConsoleOutput
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	output, err := devops.GetConsoleOutput(param.BuildID)
	if err != nil {
		ErrorResponse(c, code.GET_INFO_ERR, err.Error())
		return
	}
	SuccessResponse(c, output)
}

// @Summary 获取人工确认信息
// @Tags 构建记录
// @Produce  json
// @Param	param  query  validation.GetInputAction  true   "传入参数"
// @Success 200 {object} data.SuccessGetInputAction  		"成功返回"
// @Failure 10000 {object} data.ParamError     			    "错误返回"
// @Failure 12003 {object} data.FailGetBuildConsoleOutput   "错误返回"
// @Router /api/pipeline/build/input/action [get]
func GetInputAction(c *gin.Context) {
	var param validation.GetInputAction
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	inputAction, err := devops.GetInputAction(param.BuildID)
	if err != nil {
		ErrorResponse(c, code.GET_INFO_ERR, err.Error())
		return
	}
	SuccessResponse(c, inputAction)
}

// @Summary 人工确认
// @Tags 构建记录
// @Produce  json
// @Param	param  body  validation.InputSubmit  true   "传入参数"
// @Success 200 {object} data.SuccessInputSubmit  		"成功返回"
// @Failure 10000 {object} data.ParamError     			    "错误返回"
// @Failure 12003 {object} data.FailGetBuildConsoleOutput   "错误返回"
// @Router /api/pipeline/build/input/submit [post]
func InputSubmit(c *gin.Context) {
	var param validation.InputSubmit
	if err := c.ShouldBind(&param); err != nil {
		ErrorResponse(c, code.PARAMETER_ERR, err.Error())
		return
	}
	devops := service.NewDevOps()
	submit, _ := strconv.ParseBool(param.Submit)
	err := devops.InputSubmit(param.BuildID, submit, param.Stage, param.Name, param.Value)
	if err != nil {
		ErrorResponse(c, code.GET_INFO_ERR, err.Error())
		return
	}
	SuccessResponse(c, "确认成功")
}
